<?php

namespace IDock\Insurance\HBIC;

use IDock\IDock\IDockInterface;
use IDock\Insurance\HBIC\Request\CancelOrderRequest;
use IDock\Insurance\HBIC\Request\DownloadInsuranceRequest;
use IDock\Insurance\HBIC\Request\GetActualValueRequest;
use IDock\Insurance\HBIC\Request\HBICTokenRequest;
use IDock\Insurance\HBIC\Request\InsuranceCheckQueryRequest;
use IDock\Insurance\HBIC\Request\InsuranceCheckRequest;
use IDock\Insurance\HBIC\Request\InsuranceOrderPriceRequest;
use IDock\Insurance\HBIC\Request\InsurancePayUrlRequest;
use IDock\Insurance\HBIC\Request\NonCarOrderInquiryRequest;
use IDock\Insurance\HBIC\Request\PolicyOrderQueryRequest;
use IDock\Insurance\HBIC\Request\RenewalInquiryRequest;
use IDock\Insurance\HBIC\Request\SichuanTrafficVehicleRequest;
use IDock\Insurance\HBIC\Request\SmsCodeVerifyAndSubmitRequest;
use IDock\Insurance\HBIC\Request\UploadFileRequest;
use IDock\Insurance\HBIC\Request\VehicleModelQueryRequest;
use IDock\Insurance\HBIC\Response\CancelOrderResponse;
use IDock\Insurance\HBIC\Response\CommonResponse;
use IDock\Insurance\HBIC\Response\DownloadInsuranceResponse;
use IDock\Insurance\HBIC\Response\InsuranceConfirmResponse;
use IDock\Insurance\HBIC\Response\InsuranceOrderQueryResponse;
use IDock\Insurance\HBIC\Response\InsurancePayUrlResponse;
use IDock\Insurance\HBIC\Response\InsurancePriceQueryResponse;
use IDock\Insurance\HBIC\Response\NonCarOrderInquiryResponse;
use IDock\Insurance\HBIC\Response\NonCarProductListResponse;
use IDock\Insurance\HBIC\Response\RenewalInquiryResponse;
use IDock\Insurance\HBIC\Response\UploadFileResponse;
use IDock\Insurance\HBIC\Response\ValidateCarResponse;
use IDock\Insurance\HBIC\Response\VehicleActualValueResponse;
use IDock\Printer\NonCar\NonCarInquiryPrinter;
use IDock\Printer\NonCar\NonCarInquirySinglePrinter;
use IDock\Printer\Premium\PremiumCoveragePrinter;
use IDock\Printer\Premium\PremiumInquiryPrinter;
use IDock\Printer\UploadFilePrinter;
use IDock\Visitor\EPolicyDownloadVisitor;
use IDock\Visitor\NonCar\NonCarInquiryVisitor;
use IDock\Visitor\NonCar\NonCarProductListVisitor;
use IDock\Visitor\NonCar\NonCarProductVisitor;
use IDock\Visitor\PolicyInfoVisitor;
use IDock\Visitor\PolicyPaymentVisitor;
use IDock\Visitor\Premium\PremiumCoverageVisitor;
use IDock\Visitor\Premium\PremiumInquiryVisitor;
use IDock\Visitor\ProposalRecallVisitor;
use IDock\Visitor\ProposalStatusVisitor;
use IDock\Visitor\RenewalInquiryVisitor;
use IDock\Visitor\UnderwritingRecallVisitor;
use IDock\Visitor\UploadFileVisitor;
use IDock\Visitor\ValidateCarVisitor;
use IDock\Visitor\VehicleActualValueVisitor;
use IDock\Visitor\VehicleModelVisitor;

/**
 * 恒邦保险
 */
class HBICConstruct extends Builder implements IDockInterface
{

    protected $config = [];

    public function __construct($config)
    {
        $this->config = $config;
        $this->userCode = $config['userCode'] ?? '';
        $this->userPassword = $config['userPassword'] ?? '';
        $this->accChanId = $config['accChanId'] ?? '';
        $this->key = $config['key'] ?? '';
        $this->gateway1 = $config['gateway1'] ?? '';
        $this->gateway2 = $config['gateway2'] ?? '';
        $this->gateway3 = $config['gateway3'] ?? '';
        $this->username = $config['username'] ?? '';
        $this->password = $config['password'] ?? '';
        $this->noCarUserId = $config['noCarUserId'] ?? '';
        $this->noCarPassword = $config['noCarPassword'] ?? '';
        $this->noCarGateway = $config['noCarGateway'] ?? '';
    }

    public function renewalInquiry(RenewalInquiryVisitor $renewalInquiryVisitor): RenewalInquiryResponse
    {
        $request = new RenewalInquiryRequest();
        $request->setVisitor($renewalInquiryVisitor);

        /*** @var RenewalInquiryResponse $response */
        $response = $this->execute($request);
        return $response;
    }

    public function vehicleModel(VehicleModelVisitor $vehicleModelVisitor): CommonResponse
    {
        $request = new VehicleModelQueryRequest();
        $request->setVisitor($vehicleModelVisitor);

        /*** @var CommonResponse $response
         */
        $response = $this->execute($request);
        return $response;
    }

    /**
     * 车辆实际价格
     * @param VehicleActualValueVisitor $vehicleActualValueVisitor
     * @return
     */
    public function vehicleActualValue(VehicleActualValueVisitor $vehicleActualValueVisitor): VehicleActualValueResponse
    {
        $request = new GetActualValueRequest();
        $request->setVisitor($vehicleActualValueVisitor);

        /*** @var $response VehicleActualValueResponse */
        $response = $this->execute($request);
        return $response;
    }

    public function preInquiry(PremiumInquiryVisitor $premiumNoCarVisitor)
    {
    }

    public function validateCar(PremiumInquiryVisitor $premiumInquiryVisitor)
    {
    }

    /**
     * 非车投保
     * @param PremiumInquiryVisitor $premiumInquiryVisitor
     * @return NonCarOrderInquiryResponse
     */
    public function nonCarOrderInquiry(PremiumInquiryVisitor $premiumInquiryVisitor): NonCarOrderInquiryResponse
    {
        $request = new NonCarOrderInquiryRequest();
        $request->setVisitor($premiumInquiryVisitor);
        /*** @var NonCarOrderInquiryResponse $response */
        $response = $this->execute($request);
        return $response;
    }

    /**
     * 询价
     * @param PremiumInquiryVisitor $premiumInquiryVisitor
     * @return
     */
    public function premiumInquiry(PremiumInquiryVisitor $premiumInquiryVisitor): InsurancePriceQueryResponse
    {
        $request = new InsuranceOrderPriceRequest();
        $request->setVisitor($premiumInquiryVisitor);

        /*** @var InsurancePriceQueryResponse $response */
        $response = $this->execute($request);
        //非车信息
        if (!empty($premiumInquiryVisitor->getNonCarInquiryVisitor()->getNonCarList())) {
            $response->NcSpecialClause(($premiumInquiryVisitor->getNonCarInquiryVisitor()->getNonCarList()[0])->argc['specialClause'] ?? [], $response->printer);
            //非车险种
            $printer = $response->getPrinter();
            $nonCarInquiryPrinter = new NonCarInquiryPrinter();
            $totalPremium = 0;
            foreach ($premiumInquiryVisitor->getNonCarInquiryVisitor()->getNonCarList() as $item) {
                /*** @var $item NonCarProductVisitor */
                $single = new NonCarInquirySinglePrinter();
                $single->premium = $item->premium;
                $single->planCode = $item->planCode;
                $single->productCode = $item->productCode;
                $single->statusCode = 'success';
                $totalPremium += $single->premium * $item->insuredNum;
                $nonCarInquiryPrinter->noCarInquirySingleAppend($single);
            }
            $nonCarInquiryPrinter->totalPremium = $totalPremium;
            $printer->nonCarInquiryPrinter = $nonCarInquiryPrinter;
            $response->printer = $printer;
        }
        if ($response->isSuccess() && property_exists($response, 'printer')) {
            /**** @var PremiumInquiryPrinter $printer */
            $printer = $response->printer;
            $coverageList = $printer->coverageList;
            /**@var PremiumCoveragePrinter $value */
            foreach ($coverageList as $value) {
                /*** @var PremiumCoverageVisitor $coverageVisitor */
                foreach ($premiumInquiryVisitor->getCoverageVisitorList() as $coverageVisitor) {
                    if ($coverageVisitor->coverageCode == $value->coverageCode) {
                        $value->serviceTimes = $coverageVisitor->serviceTimes;
                    }
                }
            }
        }

        return $response;

    }

    /**
     * 核保接口
     * @param PremiumInquiryVisitor $premiumInquiryVisitor
     * @return InsuranceConfirmResponse|NonCarOrderInquiryResponse
     */
    public function underwriting(PremiumInquiryVisitor $premiumInquiryVisitor)
    {
        $request = new InsuranceCheckRequest();
        $request->setVisitor($premiumInquiryVisitor);
//        global $testResponse;
        /*        $testResponse = '<?xml version="1.0" encoding="UTF-8"?><PACKET type="RESPONSE" version="1.0" ><HEAD><REQUEST_TYPE>258</REQUEST_TYPE><RESPONSE_CODE>1</RESPONSE_CODE><ERROR_CODE>0000</ERROR_CODE><ERROR_MESSAGE>成功</ERROR_MESSAGE><LOGID></LOGID></HEAD><BODY><BASE_PART><ENQUIRYNO>02060101000020240000284</ENQUIRYNO><PREUNDWRTRESULT>9</PREUNDWRTRESULT><PACKAGECODE></PACKAGECODE><RENEWIND>0</RENEWIND><PROPOSALNO>T060101136320240000045</PROPOSALNO><PROPOSALNOBI>T060101080820240000052</PROPOSALNOBI><PROPOSALNOCI>T060101080120240000049</PROPOSALNOCI></BASE_PART><SALESFEELIST><SALESFEE><FEETYPE>355</FEETYPE><FEEPERCENT>21.0</FEEPERCENT><RISKCODE>0801</RISKCODE><FEEAMOUNT>188.21</FEEAMOUNT></SALESFEE><SALESFEE><FEETYPE>355</FEETYPE><FEEPERCENT>0.0</FEEPERCENT><RISKCODE>0808</RISKCODE><FEEAMOUNT>0.0</FEEAMOUNT></SALESFEE><SALESFEE><FEETYPE>201</FEETYPE><FEEPERCENT>4.0</FEEPERCENT><RISKCODE>0801</RISKCODE><FEEAMOUNT>35.85</FEEAMOUNT></SALESFEE><SALESFEE><FEETYPE>201</FEETYPE><FEEPERCENT>25.0</FEEPERCENT><RISKCODE>0808</RISKCODE><FEEAMOUNT>673.53</FEEAMOUNT></SALESFEE></SALESFEELIST></BODY></PACKET>';*/
        /*** @var InsuranceConfirmResponse $response */
        $response = $this->execute($request);
        if ($response->printer->inquiryNo) {
            $request1 = new UploadFileRequest();
            $request1->token = $this->token;
            $fileList = $premiumInquiryVisitor->getFileList();
            foreach ($fileList as $value) {
                $visitor = new UploadFileVisitor();
                $visitor->fileList[0] = [
                    'type' => $value['type'],
                    'url' => $value['url'],
                    'base64' => $value['base64']
                ];
                $visitor->inquiryNo = $response->printer->inquiryNo;
                $visitor->argc = $premiumInquiryVisitor->getExtInfoVisitor()->argc;
                $visitor->argc['isNewCar'] = $premiumInquiryVisitor->getVehicleVisitor()->isNewVehicle;
                $request1->setVisitor($visitor);
                $this->execute($request1);
            }
        }
//        $testResponse = '';
        //非车信息
        if (!empty($premiumInquiryVisitor->getNonCarUnderwritingVisitor()->getNonCarList()) && $response->isSuccess() && in_array($response->printer->statusCode, ['U1', 'U3'])) {
            $response1 = $this->nonCarOrderInquiry($premiumInquiryVisitor);
            if (!$response1->isSuccess()) {
                return $response1;
            }
            $response->printer->argc['nonCarApplyNo'] = $response1->printer->argc['nonCarApplyNo'] ?? '';
            $response->printer->argc['nonCarPremium'] = $premiumInquiryVisitor->getNonCarUnderwritingVisitor()->getNonCarList()[0]->premium ?? '0';
        }
        return $response;
    }

    public function policyPayment(PolicyPaymentVisitor $paymentVisitor): InsurancePayUrlResponse
    {
        $request = new InsurancePayUrlRequest();
        $request->setVisitor($paymentVisitor);
//        global $testResponse;
        /*        $testResponse = '<?xml version="1.0" encoding="UTF-8"?><packet><body><baseInfo><businessNo>01060100202403000008</businessNo><payUrl>https://paysit.hbins.com.cn/hbins/gainPay?businessNo=01060100202403000008&sign=847f1e0855b5838bc80d8a1e18d99d9c</payUrl><expireDate>2024-03-29 00:00:00</expireDate><msgCode>00</msgCode></baseInfo></body></packet>';*/
        /*** @var InsurancePayUrlResponse $response */
        $response = $this->execute($request);
        return $response;
    }

    public function uploadFile(UploadFileVisitor $uploadFileVisitor): UploadFileResponse
    {
        $response = new UploadFileResponse();
        $response->printer = new UploadFilePrinter();
        $response->setCode(200);
        return $response;
    }

    /**
     * 订单状态
     * @param ProposalStatusVisitor $proposalStatusVisitor
     * @return InsuranceOrderQueryResponse
     */
    public function proposalStatus(ProposalStatusVisitor $proposalStatusVisitor): InsuranceOrderQueryResponse
    {
        $request = new InsuranceCheckQueryRequest();
        $request->setVisitor($proposalStatusVisitor);

        /*** @var InsuranceOrderQueryResponse $response */
        $response = $this->execute($request);
        return $response;
    }

    public function proposalRecall(ProposalRecallVisitor $revokeVisitor)
    {
    }

    public function underwritingRecall(UnderwritingRecallVisitor $recallVisitor): CancelOrderResponse
    {
        $request = new CancelOrderRequest();
        $request->setVisitor($recallVisitor);

        /*** @var CancelOrderResponse $response */
        $response = $this->execute($request);
        return $response;
    }

    public function EPolicyDownload(EPolicyDownloadVisitor $EPolicyVisitor): DownloadInsuranceResponse
    {
        $request = new DownloadInsuranceRequest();
        $request->token = 'Bearer ' . $this->token;
        $request->setVisitor($EPolicyVisitor);

        /*** @var DownloadInsuranceResponse $response */
        $response = $this->execute($request);
        return $response;
    }

    /**
     * 获取恒邦token
     * @return mixed|string
     */
    public function getAuthorizationToken()
    {
        $token = new HBICTokenRequest();
        $token->password = $this->password;
        $token->username = $this->username;

        /*** @var CommonResponse $response
         */
        $response = $this->execute($token);
        return $response->getBody()['id_token'] ?? '';

    }

    public function policyInfo(PolicyInfoVisitor $policyInfoVisitor)
    {
    }


    /**
     * 保单查询
     */
    public function PolicyOrderQuery($policyNo, $vinNo, $licenseNo, $uwYear): CommonResponse
    {
        $request = new PolicyOrderQueryRequest();
        $request->setPolicyNo($policyNo);
        $request->setVinNo($vinNo);
        $request->setLicenseNo($licenseNo);
        $request->setUwYear($uwYear);

        /*** @var CommonResponse $response */
        $response = $this->execute($request);
        return $response;
    }

    public function SmsCodeVerifyAndSubmit($verificationType, $businessNo, $riskCode, $businessType, $verificationCode = ''): CommonResponse
    {
        $request = new SmsCodeVerifyAndSubmitRequest();
        $request->setVerificationType($verificationType);
        $request->setBusinessNo($businessNo);
        $request->setBusinessType($businessType);
        $request->setVerificationCode($verificationCode);

        /*** @var CommonResponse $response */
        $response = $this->execute($request);
        return $response;
    }

    public function SichuanTrafficVehicleRequest($licenseKindCode, $licenseNo, $Vin): CommonResponse
    {
        $request = new SichuanTrafficVehicleRequest();
        $request->setLicenseKindCode($licenseKindCode);
        $request->setLicenseNo($licenseNo);
        $request->setVin($Vin);

        /*** @var CommonResponse $response */
        $response = $this->execute($request);
        return $response;
    }


    public function nonCarProductList(NonCarProductListVisitor $nonCarProductListVisitor): NonCarProductListResponse
    {
        $response = new NonCarProductListResponse();
        $response->seat = $nonCarProductListVisitor->seats;
        $response->printerInit();
        $response->setCode(200);
        return $response;
    }

    /**
     * 非车询价
     * @param NonCarInquiryVisitor $nonCarInquiryVisitor
     * @return void
     */
    public function nonCarInquiry(NonCarInquiryVisitor $nonCarInquiryVisitor)
    {
    }

    /**
     * 非车核保
     * @param NonCarInquiryVisitor $inquiryPrinter
     * @return void
     */
    public function nonCarUnderwriting(NonCarInquiryVisitor $inquiryPrinter)
    {
    }

    public function validateCarCode(ValidateCarVisitor $validateCarVisitor): ValidateCarResponse
    {
        $response =  new ValidateCarResponse(200);
        $response->printerInit();

        return $response;
    }

    /**
     * 新车备案
     * @return void
     */
    public function newVehicleRegistration(PremiumInquiryVisitor $premiumInquiryVisitor)
    {
    }
}
